﻿using LinqToDB.Schema;
using LinqToDB.Mapping;

namespace LinqToDB.Metadata
{
	/// <summary>
	/// Column mapping attributes, used with <see cref="ColumnAttribute"/> mapping attribute.
	/// </summary>
	public sealed class ColumnMetadata
	{
		/// <summary>
		/// Column name. When not specified, attribute owner (field or property) name will be used (with same casing).
		/// </summary>
		public string?       Name              { get; set; }
		/// <summary>
		/// Column database type attributes.
		/// </summary>
		public DatabaseType? DbType            { get; set; }
		/// <summary>
		/// Column <see cref="DataType"/> type kind.
		/// </summary>
		public DataType?     DataType          { get; set; }
		/// <summary>
		/// Nullability of column.
		/// </summary>
		public bool          CanBeNull         { get; set; }
		/// <summary>
		/// Specify, that column should be skipped on record creation operations (e.g. INSERT), except cases when user
		/// explicitly specify column in insert expression.
		/// </summary>
		public bool          SkipOnInsert      { get; set; }
		/// <summary>
		/// Specify, that column should be skipped on record update operations (e.g. UPDATE), except cases when user
		/// explicitly specify column in update expression.
		/// </summary>
		public bool          SkipOnUpdate      { get; set; }
		/// <summary>
		/// Specify, that column value generated by database on record creation operation. Enables same behavior
		/// as <see cref="SkipOnInsert"/> and <see cref="SkipOnUpdate"/> properties and additionally provides
		/// support for identity retrieval on insert operations with identity retrieval (currently limited only
		/// to integer types).
		/// </summary>
		public bool          IsIdentity        { get; set; }
		/// <summary>
		/// Column is a part of primary key.
		/// </summary>
		public bool          IsPrimaryKey      { get; set; }
		/// <summary>
		/// Column ordinal in composite primary key.
		/// </summary>
		public int?          PrimaryKeyOrder   { get; set; }
		/// <summary>
		/// Mapping configuration name.
		/// </summary>
		public string?       Configuration     { get; set; }
		/// <summary>
		/// Contains mapped member name, when attribute applied not to member directly but to entity class/interface.
		/// See <see cref="ColumnAttribute.MemberName"/> for more details.
		/// </summary>
		public string?       MemberName        { get; set; }
		/// <summary>
		/// Field or property name to use as data storage in load operations.
		/// </summary>
		public string?       Storage           { get; set; }
		/// <summary>
		/// Contains custom column create format string (SQL), used by create table APIs.
		/// See <see cref="ColumnAttribute.CreateFormat"/> for more details.
		/// </summary>
		public string?       CreateFormat      { get; set; }
		/// <summary>
		/// When set to false, marks member as non-column propery/field, which shold be ignored by linq2db.
		/// Default value: <c>true</c>.
		/// </summary>
		public bool          IsColumn          { get; set; } = true;
		/// <summary>
		/// Indicates that current column contains discriminator value for mapping with inheritance.
		/// </summary>
		public bool          IsDiscriminator   { get; set; }
		/// <summary>
		/// When set to <c>true</c>, column will be excuded from select operation with implicit columns. E.g.
		/// <c>db.Table.ToList()</c>.
		/// </summary>
		public bool          SkipOnEntityFetch { get; set; }
		/// <summary>
		/// Contains column ordinal for create table APIs.
		/// </summary>
		public int?          Order             { get; set; }
	}
}
